package com.example.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.example.common.enums.ResultCodeEnum;
import com.example.common.exception.BusinessException;
import com.example.common.interface_constants.Constants;
import com.example.common.properties.JwtProperties;
import com.example.common.util.JwtUtil;
import com.example.domain.User;
import com.example.domain.dto.UserDto;
import com.example.domain.vo.UserVo;
import com.example.mapper.WebMapper;
import com.example.service.WebService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class WebServiceImpl implements WebService {
    @Autowired
    private WebMapper webMapper;

    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 登录
     *
     * @param userDto
     * @return
     */
    @Override
    public UserVo login(UserDto userDto, HttpSession session) {
        if (ObjectUtil.isEmpty(userDto.getUsername()) || ObjectUtil.isEmpty(userDto.getPassword()) || ObjectUtil.isEmpty(userDto.getCode())) {
            throw new BusinessException(ResultCodeEnum.PARAM_LOST_ERROR);
        }

        Boolean b = validateCaptcha(userDto.getCode(), session);

        if (b) {
            throw new BusinessException(ResultCodeEnum.CAPTCHA_ERROR);
        }

        User user = webMapper.selectByUsername(userDto.getUsername());

        //空返回true isEmpty会检查String list array 的长度是否为0 其他对象则检查是否为null
        if (ObjectUtil.isEmpty(user)) {
            throw new BusinessException(ResultCodeEnum.USER_NOT_EXIST_ERROR);
        }

        String password = DigestUtils.md5DigestAsHex(userDto.getPassword().getBytes());

        if (!password.equals(user.getPassword())) {
            throw new BusinessException(ResultCodeEnum.USER_User_ERROR);
        }

        //登录成功后，生成用户token令牌
        Map<String, Object> claims = new HashMap<>();
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        claims.put("userId", user.getId());
        String token = JwtUtil.createJWT(
                jwtProperties.getUserSecretKey(),
                jwtProperties.getUserTtl(),
                claims);

        userVo.setToken(token);
        return userVo;
    }

    /**
     * 注册
     *
     * @param userDto
     * @return
     */
    @Override
    public void register(UserDto userDto, HttpSession session) {
        if (ObjectUtil.isEmpty(userDto.getUsername()) || ObjectUtil.isEmpty(userDto.getPassword())) {
            throw new BusinessException(ResultCodeEnum.PARAM_LOST_ERROR);
        }

        Boolean b = validateCaptcha(userDto.getCode(), session);

        if (b) {
            throw new BusinessException(ResultCodeEnum.CAPTCHA_ERROR);
        }

        //1. 注册判断数据库是否存在当前用户名的数据
        User user = webMapper.selectByUsername(userDto.getUsername());
        //2. 用户不为空则代表当前用户名重复，不能注册，抛出异常
        if (ObjectUtil.isNotNull(user)) {
            throw new BusinessException(ResultCodeEnum.USER_EXIST_ERROR);
        }
        //4. 判断前端传递的数据中有没有姓名，没有则把当前数据的用户名赋值给姓名
        if (ObjectUtil.isEmpty(userDto.getName())) {
            userDto.setName(userDto.getUsername());
        }

        if (ObjectUtil.isNull(userDto.getPassword())) {
            userDto.setPassword(DigestUtils.md5DigestAsHex(Constants.USER_DEFAULT_PASSWORD.getBytes()));
        }

        userDto.setCreatedAt(LocalDateTime.now());
        userDto.setUpdatedAt(LocalDateTime.now());
        userDto.setPassword(DigestUtils.md5DigestAsHex(userDto.getPassword().getBytes()));

        int i = webMapper.register(userDto);
        if (i == 0) {
            throw new BusinessException(ResultCodeEnum.SYSTEM_ERROR);
        }
    }

    /**
     * 根据id查询用户
     *
     * @param id
     * @return
     */
    @Override
    public User selectById(Integer id) {
        return webMapper.selectById(id);
    }

    @Override
    public void updateUser(User user) {
        int i = webMapper.updateUser(user);
        if (i == 0) {
            throw new BusinessException(ResultCodeEnum.SYSTEM_ERROR);
        }
    }

    @Override
    public User getPersonInfo(Integer userId) {
        return webMapper.selectById(userId);
    }

    @Override
    public User updatePersonInfo(User user) {
        user.setUpdatedAt(LocalDateTime.now());
        if (ObjectUtil.isNotEmpty(user.getPassword())) {
            user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        }
        int i = webMapper.updateUser(user);
        if (i == 0) {
            throw new BusinessException(ResultCodeEnum.SYSTEM_ERROR);
        }
        return webMapper.selectById(user.getId());
    }

    @Override
    public void validatePwd(User user) {
        User user1 = webMapper.selectById(user.getId());
        String newPwd = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        if (!user1.getPassword().equals(newPwd)) {
            throw new BusinessException(ResultCodeEnum.PARAM_PASSWORD_ERROR);
        }
    }

    public Boolean validateCaptcha(String captcha, HttpSession session) {
        // 获取存储的验证码和生成时间
        String code = (String) session.getAttribute(Constants.CAPTCHA_KEY);
        Date createTime = (Date) session.getAttribute(Constants.CAPTCHA_DATE);
        System.out.println("输入验证码->" + captcha);
        System.out.println("正确验证码->" + code);
        // 判断验证码是否正确(验证码一般忽略大小写)
        if (captcha.equalsIgnoreCase(code)) {
            // 判断验证码是否过时
            return createTime == null || System.currentTimeMillis() - createTime.getTime() > Constants.EXPIRATION_TIME;
        }
        return true;
    }
}
